package com.higgins.client.agentapp.components;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.higgins.client.GreetingService;
import com.higgins.client.GreetingServiceAsync;
import com.higgins.client.agentapp.datamodel.AdvertisedJobDTO;
import com.higgins.client.agentapp.datamodel.AgencyDTO;
import com.higgins.client.agentapp.datamodel.AgentDTO;
import com.higgins.client.agentapp.datamodel.CorrespondenceDTO;
import com.higgins.client.agentapp.datamodel.JobSiteDTO;
import com.higgins.client.agentapp.service.AgentAppService;
import com.higgins.client.agentapp.service.AgentAppServiceAsync;
import com.higgins.client.dataModel.CoveringLetterDTO;
import com.higgins.client.dataModel.RecipientCountDTO;
import com.higgins.client.dataModel.StatusDTO;
import com.higgins.client.dataModel.StrategyDTO;
import com.higgins.client.dataModel.StrategyRecipientCountDTO;
import com.higgins.client.dataModel.StrategyRecipientDTO;
import com.higgins.client.generic.components.GenericColumn;
import com.higgins.client.generic.components.GenericTable;
import com.higgins.server.agentapp.datamodel.AdvertisedJob;

public class CorrespondenceTable extends GenericTable	{
	private static final Logger log = Logger.getLogger(CorrespondenceTable.class.getName());
	private final AgentAppServiceAsync agentAppService = GWT
			.create(AgentAppService.class);
	private AdvertisedJobDTO advertisedJobDTO = null;
	private Long agencyId = null;
	
	public CorrespondenceTable(CorrespondenceColumns columns)	{
		super(columns);
	}
	public void setAdvertisedJobDTO(AdvertisedJobDTO advertisedJobDTO)	{
		this.advertisedJobDTO = advertisedJobDTO;
		retrieveDTOs(advertisedJobDTO);
	}
	public void setAgencyId(Long agencyId)	{
		this.agencyId = agencyId;
		((CorrespondenceColumns)genericColumns).setAgencyId(agencyId);
	}
	
	protected void addObject(int row, int column, Object object)	{
		ensureRowAvailable(row);
		GenericColumn genericColumn = genericColumns.getColumn(column);
		if (genericColumn.getType().equals(AgentDTO.class))	{
			addAgentDTO(row, column, object, genericColumn);
		} 
	}

	protected void addAgentDTO(int row, int column, Object object, GenericColumn genericColumn)	{
		final ListBox listBox = new ListBox();
		final int finalRow = row; 
		int count = 1;
		listBox.addItem("");
		List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
		for (Object listItem:(list!=null?list:new ArrayList<Object>()))	{
			String item = ((AgentDTO)listItem).getName();
			listBox.addItem(item);
			if (((String)object).equals(item))	{
				listBox.setSelectedIndex(count);
			}
			count++;
		}
		listBox.addChangeHandler(new ChangeHandler() {
	        public void onChange(ChangeEvent changeEvent) {
	            SelectElement selectElement = listBox.getElement().cast();
	            selectElement.getOptions().getItem(0).setDisabled(true);
	            updateItemCell(finalRow);

	        }
	    });
		setWidget(row, column, listBox);
 		getCellFormatter().addStyleName(row, column, "FlexTable-normCell");		
	}		
	
	private List<List<Object>> convertDTOtoRowArray(List<CorrespondenceDTO> correspondenceDTOs)	{
		List<List<Object>> rows = new ArrayList<List<Object>>();
		for (CorrespondenceDTO correspondenceDTO:correspondenceDTOs)	{
			List<Object> row = new ArrayList<Object>();
			row.add(correspondenceDTO.getId());
			row.add(correspondenceDTO.getTimestamp()!=null?correspondenceDTO.getTimestamp():"");
			row.add(correspondenceDTO.getAgentDTO()!=null?correspondenceDTO.getAgentDTO().getName():"");
			row.add(correspondenceDTO.getDescription()!=null?correspondenceDTO.getDescription():"");
			rows.add(row);
		}
		return rows;
	}
	
	public void updateItemCell(int row)	{
		CorrespondenceDTO correspondenceDTO = new CorrespondenceDTO();
		correspondenceDTO.setId(getId(row));
		correspondenceDTO.setTimestamp(getDate(row, 1));
		correspondenceDTO.setAgentDTO(getAgentDTO(row, 2));
		correspondenceDTO.setDescription(getText(row, 3));
		correspondenceDTO.setAdvertisedJobDTO(advertisedJobDTO);
		updateRow(correspondenceDTO);
	}
	
	protected void retrieveDTOs(AdvertisedJobDTO advertisedJobDTO)	{
		try {
			agentAppService.retrieveCorrespondences(advertisedJobDTO.getId(), new AsyncCallback<List<CorrespondenceDTO>>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(List<CorrespondenceDTO> result) {
						loadData(convertDTOtoRowArray(result));
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} */
	}	

	private void updateRow(CorrespondenceDTO correspondenceDTO)	{
		try {
			agentAppService.updateCorrespondence(correspondenceDTO, new AsyncCallback<String>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("FixedOutgoingDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						setRowIdAfterUpdate(result);
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("FixedOutgoingDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 		*/
	}
		
	public AgentDTO getAgentDTO(int row, int column)	{
		try	{
			ListBox listBox = (ListBox)getWidget(row, column);
			int selectedIndex = listBox.getSelectedIndex();
			String agent = listBox.getItemText(selectedIndex);
			return getAgentDTO(agent);
		} catch (Exception e)	{
			return null;
		}
	}
	@SuppressWarnings("unchecked")
	public AgentDTO getAgentDTO(String string)	{
		for (GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType()==(AgentDTO.class))	{
				if (genericColumn.getList()!=null)	{
					for (AgentDTO dto:(List<AgentDTO>)genericColumn.getList())	{
						if (dto.getName().equals(string))	{
							return dto;
						}
					}
				}
			}
		}
		return null;
	}		
	protected String statusField(StrategyDTO dto)	{
		Integer status = dto.getStatus();
		if (status!=null)	{
			switch (status)	{
			case 0:
				return "None";
			case 1:
				return "Requested";
			case 2:
				return "Generated";
			case 3:
				return "Posted";
			}
		} 
		return "";
	}
	protected Integer getStatusColumn()	{
		for(GenericColumn genericColumn:genericColumns.getColumns())	{
			if (genericColumn.getType().equals(StatusDTO.class))
				return genericColumn.getIndex();
		}
		return null;
	}
    protected void checkBoxSet(Long id) {
        agentAppService.deleteCorrespondence(id, new AsyncCallback<Boolean>() {
            @Override
            public void onFailure(Throwable caught) {
                
            }

            @Override
            public void onSuccess(Boolean result) {
                refresh();
            } });
    }	
}